<?php
namespace Twoir\System\Support;

/**
 * 构造语句前置处理
 *
 * cighsen02 qq 365182575
 * time: 2022.05.26
 * lastupdate: 2024.08.24
*/
trait ParseTrait
{
    const REGEX = [
        'where'     => '/(\w+)\s+(>=|<=|>|<|in|like)/i',
        'update'    => '/\w+\s+(\+|-)\s+(\d+)/'
    ];

    /**
	 * 简单数组转字符串, 给值增加""，
	 *
	 * @param array $data
	 * @return string
	 */
	private static function value2String(array $data, string $type = 'string'): string
	{
		array_walk($data, function(&$item) use($type) {

			if ('string' === $type) $item = "'" . $item . "'";

		});

		return implode(',', $data);
	}

    /**
     * 询查构造
	 *
	 * @param array $where
	 * @param bool $prepare
	 * @return array;
	 */
    public static function parseWhere(array $where = [], bool $prepare = true): array
	{
		if (empty($where)) return ['where' => '', 'data'  => []];

		$field  = static::fieldType();
		$str 	= '';
		$data   = [];
		foreach((array)$where as $key => $value) {

			//去除null值
			if (null !== $value) {

				//默认
				$eq = ' = ';
				//增加空判断可以加快
				if (str_contains($key, ' ') && preg_match(static::REGEX['where'], $key, $matches)) {
					//真正key
					$key = $matches[1];
					//in处理
					if ('in' === $matches[2] && is_array($value)) {

						$value = array_values($value);
						if (count($value) > 1) {

							$type   = isset($field[$key]) && $field[$key] ? $field[$key] : 'string';
							$eq     = 'IN';
							$value  = '(' . static::value2String($value, $type) . ')';
						}
						else {

							$value = $value[0];
						}
					}
					else {

						$eq = strtoupper($matches[2]);
					}
				}

				//值的类型处理,字符串时
				if (!isset($field[$key]) || ('string' === $field[$key] && !in_array($eq, ['IN','>=','<=','>','<']))) $value = "'" . $value . "'";

				$data[$key] = $value;
				$str .= ($str ? ' AND ' : '') . '`' . $key . '`' . $eq . $value;
			}
		}

		return [
			'where' => $str ? ' WHERE ' . $str : '',
			'data'	=> $data
		];
	}

	/**
	 * 构造插入语句
	 *
	 * @param array $data
	 * @return array
	 */
	public static function parseInsert(array $data): array
	{
		if (empty($data)) return ['key' => '', 'value' => ''];
		//去null值
		$data   = array_filter($data, fn($item) => null !== $item);
		$field  = static::fieldType();

		array_walk($data, function (&$value, $key) use ($field) {

		    $value = !isset($field[$key]) || 'string' === $field[$key] ? "'" . $value . "'" : $value;

		});

		return ['key' => '`'. implode('`,`', array_keys($data)) . '`', 'value' => implode(',', array_values($data))];
	}

	/**
	 * 构造更新语句
	 *
	 * @param array $add
	 * @return string
	*/
	public static function parseUpdate(array $add): string
	{
		//去null值
		$add    = array_filter((array)$add, fn($item) => null !== $item);
		$field  = static::fieldType();
		$str    = '';
	    foreach($add as $key => $value) {

			if (!isset($field[$key]) || 'string' === $field[$key] || 1 !== preg_match('/\w+\s+(\+|-)\s+(\d+)/', $value)) {

	            $str .= ($str ? ',' : '') . '`' . $key . '` = ' . "'" . $value . "'";
	        }
			else {

				$str .= ($str ? ',' : '') . '`' . $key . '` = ' . $value;
			}
	    }

	    return $str;
	}
}
